package com.projectsexception.festivales.schedule.view;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.projectsexception.festivales.R;
import com.projectsexception.festivales.db.DBAdapter;
import com.projectsexception.festivales.favorites.model.Favorite;
import com.projectsexception.festivales.provider.model.Show;
import com.projectsexception.festivales.setup.ProjectResources;
import com.projectsexception.festivales.util.ShowComparator;

public class ScheduleViewInflater extends AbstractTabScheduleViewInflater {
    
    private static final int STAGES_SIZE = 150;
    
    public ScheduleViewInflater(Activity activity) {
        super(activity);
    }

    @Override
    public void inflateMainContent(Date actualDate) {
        ViewGroup mainContent = (ViewGroup) activity.findViewById(R.id.main_content);
        mainContent.removeAllViews();
        ViewGroup main = (ViewGroup) inflater.inflate(R.layout.tab_schedule_view_schedule, null);
        mainContent.addView(main);
        
        final ProjectResources res = ProjectResources.getInstance();
        List<Show> shows = res.getShowsInDate(actualDate);
        final DBAdapter dbAdapter = DBAdapter.getInstance(activity);
        List<Favorite> favorites = dbAdapter.getFavorites();
        
        String minTime = null;
        String maxTime = null;
        for (Show show : shows) {
            // Recuperamos la hora menor y la mayor
            if (minTime == null || ShowComparator.compareTimes(show.getStartTime(), minTime) <= 0) {
               minTime = show.getStartTime();
            }
            if (maxTime == null || ShowComparator.compareTimes(show.getEndTime(), maxTime) >= 0) {
                maxTime = show.getEndTime();
            }
        }        

        // Aquí guardo la última hora de cada show, pero la primera vez
        // será donde empieza el tiempo
        Map<String, String> lastShows = new HashMap<String, String>();
        for (Show show : shows) {
            lastShows.put(show.getStage().getId(), minTime);
        }
        
        // Pintamos las horas
        inflateTimes(minTime, maxTime);
        
        // Ahora pintamos los grupos, calculando su tamaño en función de su espacio   
        TextView t;
        LinearLayout stage;
        ViewGroup layout;
        Map<String, ViewGroup> stagesMap = new HashMap<String, ViewGroup>();
        LinearLayout layoutStages = (LinearLayout) activity.findViewById(R.id.stages);
        int numStages = 0;
        for (final Show show : shows) {
            if (!stagesMap.containsKey(show.getStage().getId())) {
                /*
                 * Si no se ha pintado el nombre del escenario se pinta
                 * y se añade el layout de la derecha al mapa con clave = al id del escenario
                 * 
                 */
                stage = (LinearLayout) inflater.inflate(R.layout.tab_schedule_horizontal_sep, null);
                layoutStages.addView(stage);
                
                layout = (ViewGroup) stage.findViewById(R.id.horizontal_content);
                layout.setBackgroundColor(Color.parseColor(colors[numStages % 2]));
                
                layout = (ViewGroup) stage.findViewById(R.id.horizontal_content_left);
                t = new TextView(activity);
                t.setLayoutParams(new ViewGroup.LayoutParams(STAGES_SIZE, ViewGroup.LayoutParams.WRAP_CONTENT));
                t.setText(show.getStage().getName());
                t.setGravity(Gravity.CENTER);
                t.setTextColor(Color.BLACK);
                layout.addView(t);
                
                layout = (ViewGroup) stage.findViewById(R.id.horizontal_content_right);
                stagesMap.put(show.getStage().getId(), layout);
                numStages++;
            } else {
                layout = stagesMap.get(show.getStage().getId());
            }
            
            // Le ponemos un padding izquierdo igual a la diferencia entre la primera 
            // hora (o la última hora del show) y la hora de comienzo del grupo
            int leftPadding = ShowComparator.minutes(lastShows.get(show.getStage().getId()), show.getStartTime());            
            // Se pinta el grupo en su layout con un espacio igual a 2px por minuto
            int width = ShowComparator.minutes(show.getStartTime(), show.getEndTime());
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(width * 2, LinearLayout.LayoutParams.WRAP_CONTENT);
            View layoutBand = createBandView(show, favorites, new int[] {leftPadding * 2, 0, 0, 0}, layoutParams);                        
            layout.addView(layoutBand);
            lastShows.put(show.getStage().getId(), show.getEndTime());
        }
    }
    
    private void inflateTimes(String minTime, String maxTime) {
        LinearLayout layoutTimes = (LinearLayout) activity.findViewById(R.id.times);
        layoutTimes.setPadding(STAGES_SIZE, 0, 0, 0);
        List<String> hours = createTimes(minTime, maxTime);
        TextView t;
        for (String hour : hours) {
            t = new TextView(activity);
            t.setText(hour);
            t.setGravity(Gravity.LEFT);
            t.setLayoutParams(new ViewGroup.LayoutParams(118, ViewGroup.LayoutParams.WRAP_CONTENT));
            layoutTimes.addView(t);
        }
    }
    
    private List<String> createTimes(String start, String end) {
        String[] time1 = start.split(":");
        String[] time2 = end.split(":");
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        
        Calendar startC = GregorianCalendar.getInstance();
        startC.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time1[0]));
        startC.set(Calendar.MINUTE, Integer.parseInt(time1[1]));
        Calendar endC = GregorianCalendar.getInstance();
        endC.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time2[0]));
        endC.set(Calendar.MINUTE, Integer.parseInt(time2[1]));
        if (endC.get(Calendar.HOUR_OF_DAY) < 8 && startC.get(Calendar.HOUR_OF_DAY) > 8) {
            endC.add(Calendar.DAY_OF_MONTH, 1);
        }
        
        List<String> times = new ArrayList<String>();
        times.add(start);
        startC.add(Calendar.MINUTE, 60);            
        while (startC.getTimeInMillis() < endC.getTimeInMillis()) {
            times.add(format.format(startC.getTime()));
            startC.add(Calendar.MINUTE, 60);            
        }
        
        return times;
    }

}
